﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Borg;
using PathEditor.Properties;

namespace PathEditor
{
    [Plug("Startup")]
    [Extension("PathEditor", OnCreated = "OnCreated", OnReleased = "OnReleased")]
    [ParamValue("ExecuteInMainThread", true, new string[] { })]
    public partial class PathEditor : Form, IStartup
    {
        internal class PathObject
        {
            public int ID;
            public int NameLen;
            public byte[] Name;
        }

        private byte[] _header;
        private int _count;
        private readonly List<PathObject> _path = new List<PathObject>();

        public PathEditor()
        {
            InitializeComponent();
        }

        private void BtnOpenFileClick(object sender, EventArgs e)
        {
            var open =
                new OpenFileDialog
                    {
                        Filter = Resources.PathFilter,
                        Title = Resources.SelectPath,
                        FileName = "path.data"
                    };

            if (open.ShowDialog() != DialogResult.OK || !File.Exists(open.FileName))
                return;

            var br = new BinaryReader(File.OpenRead(open.FileName));

            _header = br.ReadBytes(4);
            _count = br.ReadInt32();

            msg.Text = Resources.Total +
                _count.ToString(CultureInfo.InvariantCulture) +
                Resources.RecordsLoaded;
            
            for (var i = 0; i < _count; ++i)
            {
                var pathObject =
                    new PathObject
                        {
                            ID = br.ReadInt32(),
                            NameLen = br.ReadInt32()
                        };

                pathObject.Name = br.ReadBytes(pathObject.NameLen);
                _path.Add(pathObject);

                listPath.Items.Add(
                    new ListViewItem(
                        new[]
                            {
                                pathObject.ID.ToString(CultureInfo.InvariantCulture),
                                Encoding.GetEncoding("GBK").GetString(pathObject.Name)
                            }));

                listPath.Items[listPath.Items.Count - 1].EnsureVisible();
            }
        }

        private void BtnSaveFileClick(object sender, EventArgs e)
        {
            var save =
                new SaveFileDialog
                    {
                        InitialDirectory = Environment.CurrentDirectory,
                        Filter = Resources.PathFilter
                    };

            if (save.ShowDialog() != DialogResult.OK)
                return;

            Cursor = Cursors.WaitCursor;
            var fs = File.OpenWrite(save.FileName);
            var bw = new BinaryWriter(fs);

            bw.Write(_header);
            bw.Write(_path.Count);

            foreach (var pathObject in _path)
            {
                bw.Write(pathObject.ID);
                bw.Write(pathObject.Name.Length);
                bw.Write(pathObject.Name);
            }

            bw.Flush();
            bw.Close();
            fs.Close();
            save.Dispose();

            Cursor = Cursors.Default;
            MessageBox.Show(Resources.FileSaved);
        }

        private void BtnExitClick(object sender, EventArgs e)
        {
            Dispose();
        }

        private void BtnAddPathClick(object sender, EventArgs e)
        {
            if (txtPath.Text == "")
                MessageBox.Show(Resources.NoPathToAdd);
            else
            {
                var pathObject =
                    new PathObject
                        {
                            ID = int.Parse(txtPathID.Text),
                            NameLen = 0,
                            Name = Encoding.Default.GetBytes(txtPath.Text)
                        };

                _path.Add(pathObject);

                listPath.Items.Add(
                    new ListViewItem(
                        new[]
                            {
                                pathObject.ID.ToString(CultureInfo.InvariantCulture),
                                txtPath.Text
                            }));

                listPath.Items[listPath.Items.Count - 1].EnsureVisible();
            }
        }

        private void BtnDeletePathClick(object sender, EventArgs e)
        {
            if (listPath.SelectedItems.Count == 0)
                MessageBox.Show(Resources.SelectPathFirst);
            else
            {
                _path.RemoveAt(listPath.SelectedItems[0].Index);
                listPath.Items.RemoveAt(listPath.SelectedItems[0].Index);
            }
        }

        private void BtnSavePathClick(object sender, EventArgs e)
        {
            if (listPath.SelectedItems.Count == 0)
                MessageBox.Show(Resources.SelectPathFirst);
            else
            {
                _path[listPath.SelectedItems[0].Index].ID = int.Parse(txtPathID.Text);
                _path[listPath.SelectedItems[0].Index].NameLen = 0;
                _path[listPath.SelectedItems[0].Index].Name = Encoding.GetEncoding("GBK").GetBytes(txtPath.Text);
                
                listPath.SelectedItems[0].SubItems[0].Text = txtPathID.Text;
                listPath.SelectedItems[0].SubItems[1].Text = txtPath.Text;
            }
        }

        private void ListPathClick(object sender, EventArgs e)
        {
            if (listPath.SelectedItems.Count == 0)
                MessageBox.Show(Resources.SelectFilePathFirst);
            else
            {
                txtPathID.Text = listPath.SelectedItems[0].SubItems[0].Text;
                txtPath.Text = listPath.SelectedItems[0].SubItems[1].Text;
            }
        }

        public void OnCreated(object sender, ExtensionEventArgs args)
        {
            Show();
        }

        public void OnReleased(object sender, ExtensionEventArgs args)
        {
            Hide();
        }

        public void Run()
        { }
    }
}
